package com.whub507.msgmanager.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whub507.msgmanager.common.ResResult;
import com.whub507.msgmanager.common.ZWWW;
import com.whub507.msgmanager.config.ZWWWConfig;
import com.whub507.msgmanager.domain.Message;
import com.whub507.msgmanager.domain.Project;
import com.whub507.msgmanager.mapper.MessageMapper;
import com.whub507.msgmanager.mapper.ProjectMapper;
import com.whub507.msgmanager.service.MessageService;
import com.whub507.msgmanager.task.ScheduledTaskManager;
import com.whub507.msgmanager.utils.TimeUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;

@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {

    @Resource
    ZWWWConfig zwwwConfig;
    @Resource
    ProjectMapper projectMapper;
    @Resource
    MessageMapper messageMapper;

    @Resource
    ScheduledTaskManager scheduledTaskManager;

    @Resource
    private RestTemplate restTemplate;

//    @Override
//    public Boolean createOrUpdateMessage(String projectName, String msgTitle, Integer type, String sendTime, String phoneNums, String content, String department, String contentType, String target, String node, Integer done) throws ParseException {
//        Project project = projectMapper.selectByName(projectName);
//        System.out.println("开始保存");
//        if (project != null) {
//            Integer pid = project.getId();
//            Message msg = this.getMsgByTitle(projectName,msgTitle);
//            Message newMsg = new Message(pid, msgTitle, type, sendTime, phoneNums, content, department, contentType, target, node, done);
//            newMsg.setDeleted(0L);
//            //判断是否为立即执行的消息
//            //此处创建或更新
//            if(msg==null){
//                messageMapper.insertMsg(newMsg);
//                if(newMsg.getType()==1){
//                    //普通短信，立即执行
//                    sentMsg(newMsg);
//                }else {
//                    //定时短信
//                    scheduledTaskManager.add(newMsg.getTitle()+"-"+newMsg.getProjectid(),newMsg);
//                }
//            }else {
//                newMsg.setId(msg.getId());
//                messageMapper.updateByTheId(newMsg);
//                if(newMsg.getType()==1){
//                    //普通短信，立即执行
//                    sentMsg(newMsg);
//                    newMsg.setDone(1);
//                }else {
//                    //定时短信
//                    scheduledTaskManager.update(newMsg.getTitle()+"-"+newMsg.getProjectid(),newMsg);
//                }
//            }
//            System.out.println("保存完毕");
//            return Boolean.TRUE;
//        }
//        return Boolean.FALSE;
//    }

    @Override
    public ResResult<Boolean> validateMessage(Integer projectId, List<String> nodeAndTitles) throws ParseException {
        Project project = projectMapper.selectById(projectId);
        Date date = new Date();
        if (project != null) {

            List<Message> validMsgs = new ArrayList<>();
            List<Message> errorMsgs = new ArrayList<>();
            try {
                nodeAndTitles.stream().forEach(a -> {
                    Message message = messageMapper.selectByProjectIdAndNodeAndTitle(projectId, a.split("-")[0], a.split("-")[1]);
                    try {
                        String[] timelist = message.getSenttime().split(";");
                        int len = timelist[timelist.length-1].equals("") ? timelist.length-1 : timelist.length;
                        for (int i = 0; i < len; i++) {
                            if (!timelist[i].equals("立即") && date.after(TimeUtils.string2Date(timelist[i]))) {
                                errorMsgs.add(message);
                                break;
                            }
                            else if (i == timelist.length-1){
                                validMsgs.add(message);
                            }
                        }
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                });
            }catch (Exception e){
                return ResResult.error(505, "请检查日期格式");
            }
            if (errorMsgs.size() > 0){
                StringBuilder error = new StringBuilder();
                error.append("短信(");
                errorMsgs.stream().forEach(a -> {
                    error.append("标题：");
                    error.append(a.getTitle());
                    error.append("，节点：");
                    error.append(a.getNode());
                    error.append("；");
                });
                error.append(")的发送时间已过，请检查并修改后提交。");
                return ResResult.error(505, error.toString());
            }
            validMsgs.stream().forEach(a -> {
                String[] timelist = a.getSenttime().split(";");
                int len = timelist[timelist.length-1].equals("") ? timelist.length-1 : timelist.length;
                for (int i = 0; i < len; i++) {
                    if (timelist[i].equals("立即")){
                        sentMsg(a);
                    }
                    else {
                        a.setDone(1);
                        messageMapper.updateByTheId(a);
                        //定时短信
                        try {
                            a.setSenttime(timelist[i]);
                            scheduledTaskManager.add(a.getTitle()+"-"+a.getProjectid()+"-"+a.getNode()+"-"+a.getSenttime(), a);
                        } catch (ParseException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            });

            return ResResult.ok(Boolean.TRUE, "提交成功");
        }
        return ResResult.error(404, "不存在此项目");
    }

    @Override
    public ResResult<Boolean> uploadMessage(MultipartFile file, Integer projectId) {
        System.out.println("开始上传");
        try {
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file.getInputStream());
            Sheet sheet = xssfWorkbook.getSheetAt(0);
            Map<String, Message> map = new HashMap<>();
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                String title = sheet.getRow(i).getCell(0).toString();
                if (title == null || title.equals(""))
                    continue;
                String node = sheet.getRow(i).getCell(1).toString();
                String msgKey = title+"_"+node;
                if (!map.containsKey(msgKey)){
                    String type = sheet.getRow(i).getCell(2).toString();
                    String sendTime = sheet.getRow(i).getCell(3).toString();

                    if (!sendTime.equals("立即"))
                        sendTime = sendTime.substring(1, sendTime.length()-1);
                    String phoneNums = new DecimalFormat("0").format(sheet.getRow(i).getCell(4).getNumericCellValue()) + "、";
                    String department = sheet.getRow(i).getCell(5).toString();
//                    String contentType = sheet.getRow(i).getCell(6).toString();
//                    String target = sheet.getRow(i).getCell(7).toString();
                    String content = sheet.getRow(i).getCell(8).toString();
                    content = "【湖北省审计厅-"+department+"】"+content;
                    Integer done = 0;
                    // 0 未提交 1 未发送 2 已发送 3 发送异常
                    Message message = new Message(projectId, title, type, sendTime, phoneNums, content, node, done);
                    map.put(msgKey, message);
                }
                else {
                    String phoneNums = new DecimalFormat("0").format(sheet.getRow(i).getCell(4).getNumericCellValue()) + "、";
                    phoneNums = map.get(msgKey).getPhonenums() + phoneNums;
                    map.get(msgKey).setPhonenums(phoneNums);
                }
            }

            for (Map.Entry<String, Message> entry:map.entrySet()){
                Message tmp = messageMapper.selectByProjectIdAndNodeAndTitle(entry.getValue().getProjectid(), entry.getValue().getNode(), entry.getValue().getTitle());
                if (tmp != null)
                    return ResResult.error(503, "主键(标题-节点)重复，请检查后重新上传");
            }

            for(Map.Entry<String, Message> entry:map.entrySet()){
                messageMapper.insertMsg(entry.getValue());
            }
            String resmsg = "短信上传成功";
            return ResResult.ok(Boolean.TRUE, resmsg);

        } catch (IOException e) {
            return ResResult.error(502,"短信上传失败");
        }
    }

    @Override
    public ResResult<Boolean> formUploadMessage(Message message) {
        Message tmp = messageMapper.selectByProjectIdAndNodeAndTitle(message.getProjectid(), message.getNode(), message.getTitle());
        if (tmp != null)
            return ResResult.error(503, "主键(标题-节点)重复，请检查后重新上传");
        message.setDone(0);
        message.setPhonenums(message.getPhonenums().replace(";", "、"));
        messageMapper.insertMsg(message);
        return ResResult.ok(Boolean.TRUE, "短信上传成功");
    }

    @Override
    public List<Message> searchMessage(Integer projectId, String keyWord){
        List<Message> messageList = messageMapper.selectAllByKeyWord(keyWord, projectId);
        return messageList;
    }


    @Override
    public void downloadMsgTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode("短信模板" + ".xlsx", "UTF-8"));

        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("短信模板.xlsx");
        byte[] buf = new byte[1024];
        while (in.read(buf) > 0) {
            response.getOutputStream().write(buf, 0, buf.length);
        }
        in.close();
    }



    @Override
    public Boolean downloadMsg(HttpServletRequest request, HttpServletResponse response,Integer projectId, String node, String title) throws IOException {
        Message msg = messageMapper.selectByProjectIdAndNodeAndTitle(projectId, node, title);
        try(Workbook workbook=new XSSFWorkbook()){
            Sheet sheet=workbook.createSheet("msg1");
            Row header=sheet.createRow(0);
            header.createCell(0).setCellValue("短信标题");
            header.createCell(1).setCellValue("项目节点");
            header.createCell(2).setCellValue("短信类型");
            header.createCell(3).setCellValue("发送时间");
            header.createCell(4).setCellValue("发送对象");
            header.createCell(5).setCellValue("部门");
            header.createCell(6).setCellValue("通知类型");
            header.createCell(7).setCellValue("接收人员称呼");
            header.createCell(8).setCellValue("短信内容");

            String[] phones = msg.getPhonenums().split(",");//此处多了一个空元素在末尾
            for (int i = 1; i <= phones.length; i++) {
                Row row = sheet.createRow(i);
                row.createCell(4).setCellValue(phones[i - 1]);
            }
            Row row = sheet.getRow(1);
            row.createCell(0).setCellValue(msg.getTitle());
            row.createCell(1).setCellValue(msg.getNode());
            row.createCell(2).setCellValue(msg.getType());
            row.createCell(3).setCellValue("（"+msg.getSenttime()+"）");
//            row.createCell(5).setCellValue(msg.getDepartment());
//            row.createCell(6).setCellValue(msg.getContenttype());
//            row.createCell(7).setCellValue(msg.getTarget());
            row.createCell(8).setCellValue(msg.getContent());


            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode(title+".xlsx", "UTF-8"));
            // 获取输出流
            ServletOutputStream outputStream = response.getOutputStream();

            // 将工作簿写入输出流
            workbook.write(outputStream);

            // 关闭工作簿和输出流
            workbook.close();
            outputStream.close();
        }catch (Exception e){
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public List<Message> getAllMsgs(Integer projectId) {
        return messageMapper.selectAllByProjectId(projectId);
    }

    @Override
    public Boolean deleteMsg(Integer projectId, List<String> nodeAndTitles) {
        for (int i = 0; i < nodeAndTitles.size(); i++) {
            String node = nodeAndTitles.get(i).split("-")[0];
            String title = nodeAndTitles.get(i).split("-")[1];
            Message message = messageMapper.selectByProjectIdAndNodeAndTitle(projectId, node, title);
            messageMapper.deleteByTheId(message.getId());
            if(message.getDone()==1)
                scheduledTaskManager.cancel(message.getTitle()+"-"+message.getProjectid()+"-"+message.getNode());
        }

        return Boolean.TRUE;
    }

    @Override
    public ResResult<Boolean> editMsg(Message message, String preNode, String preTitle){
        Integer id = messageMapper.selectByProjectIdAndNodeAndTitle(message.getProjectid(), preNode, preTitle).getId();
        message.setId(id);
//        if (message.getSenttime() != null)
//            message.setType((message.getSenttime().equals("立即"))?1:2);
        messageMapper.updateByTheId(message);
        return ResResult.ok(Boolean.TRUE, "修改成功");
    }

    @Override
    public String sentMsg(Message message) {
        //考虑到定时短信无法通过第三方接口撤回，定时功能转交平台实现
        //因此，实际上发送给第三方接口的都是普通短信
//        String department = message.getDepartment();
//        String contentType = message.getContenttype();
//        String target = message.getTarget();
        String content = "\n" + message.getContent();

//        StringBuilder stringBuilder=new StringBuilder();

//        stringBuilder.append("\n");
//        stringBuilder.append("【");
//        stringBuilder.append("湖北省审计厅-"+message.getSenderdepart());
//        stringBuilder.append("】");
//        stringBuilder.append("\n");
//        stringBuilder.append(contentType);
//        stringBuilder.append("\n");
//        stringBuilder.append(target);
//        stringBuilder.append("：");
//        stringBuilder.append("\n");
//        stringBuilder.append("\t\t\t\t ");
//        stringBuilder.append(content);

//        content=stringBuilder.toString();

        ZWWW zwww = zwwwConfig.getZwww();

        String phonenums = message.getPhonenums();
        phonenums = phonenums.replaceAll("、", ",");
//        String url = "http://59.208.246.86:8080/sms/sendMessageInterface.do";
        String url = zwww.getUrl();

        LinkedMultiValueMap<String, String> request = new LinkedMultiValueMap<>();
        request.set("content", content);
        request.set("messagetype", "1");
        request.set("phonenums", phonenums);
//        request.set("interfaceusername", "sjt_jk_sjszhgl");
//        request.set("interfaceuserpwd", "e316ffac70bb7b5ed2a42427a44e14e8");
        request.set("interfaceusername", zwww.getName());
        request.set("interfaceuserpwd", zwww.getPassword());
        System.out.println("发送");
        message.setDone(2);
        messageMapper.updateByTheId(message);

        // 缺失：发送失败的异常处理
        String result = restTemplate.postForObject(url,request,String.class);
        System.out.println(result);

        return "ok";
    }
}
